﻿namespace Example.Configuration
{
    using System;

    using Xunit;

    public class CustomSettingsTests
    {
        [Fact]
        public void ctor()
        {
            Assert.NotNull(new CustomSettings());
        }

        [Fact]
        public void ctor_string()
        {
            Assert.NotNull(new CustomSettings("test"));
        }

        [Fact]
        public void ctor_stringEmpty()
        {
            Assert.NotNull(new CustomSettings(string.Empty));
        }

        [Fact]
        public void ctor_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new CustomSettings(null));
        }

        [Fact]
        public void is_IComparable()
        {
            Assert.IsAssignableFrom<IComparable>(new CustomSettings());
        }

        [Fact]
        public void opEquality_CustomSettingsNull_CustomSettings()
        {
            CustomSettings expression1 = null;
            var expression2 = new CustomSettings();

            Assert.False(expression1 == expression2);
        }

        [Fact]
        public void opEquality_CustomSettings_CustomSettingsNull()
        {
            var expression1 = new CustomSettings();
            CustomSettings expression2 = null;

            Assert.False(expression1 == expression2);
        }

        [Fact]
        public void opEquality_CustomSettings_CustomSettings_False()
        {
            var expression1 = new CustomSettings("foo");
            var expression2 = new CustomSettings("bar");

            Assert.False(expression1 == expression2);
        }

        [Fact]
        public void opEquality_CustomSettings_CustomSettings_Same()
        {
            var expression1 = new CustomSettings();
            var expression2 = expression1;

            Assert.True(expression1 == expression2);
        }

        [Fact]
        public void opEquality_CustomSettings_CustomSettings_True()
        {
            var expression1 = new CustomSettings();
            var expression2 = new CustomSettings();

            Assert.True(expression1 == expression2);
        }

        [Fact]
        public void opGreater_CustomSettingsNull_CustomSettings()
        {
            CustomSettings expression1 = null;
            var expression2 = new CustomSettings();

            Assert.False(expression1 > expression2);
        }

        [Fact]
        public void opGreater_CustomSettings_CustomSettingsNull()
        {
            var expression1 = new CustomSettings();
            CustomSettings expression2 = null;

            Assert.True(expression1 > expression2);
        }

        [Fact]
        public void opGreater_CustomSettings_CustomSettings_False()
        {
            var expression1 = new CustomSettings("bar");
            var expression2 = new CustomSettings("foo");

            Assert.False(expression1 > expression2);
        }

        [Fact]
        public void opGreater_CustomSettings_CustomSettings_Same()
        {
            var expression1 = new CustomSettings();
            var expression2 = expression1;

            Assert.False(expression1 > expression2);
        }

        [Fact]
        public void opGreater_CustomSettings_CustomSettings_True()
        {
            var expression1 = new CustomSettings("foo");
            var expression2 = new CustomSettings("bar");

            Assert.True(expression1 > expression2);
        }

        [Fact]
        public void opInequality_CustomSettingsNull_CustomSettings()
        {
            CustomSettings expression1 = null;
            var expression2 = new CustomSettings();

            Assert.True(expression1 != expression2);
        }

        [Fact]
        public void opInequality_CustomSettings_CustomSettingsNull()
        {
            var expression1 = new CustomSettings();
            CustomSettings expression2 = null;

            Assert.True(expression1 != expression2);
        }

        [Fact]
        public void opInequality_CustomSettings_CustomSettings_False()
        {
            var expression1 = new CustomSettings();
            var expression2 = new CustomSettings();

            Assert.False(expression1 != expression2);
        }

        [Fact]
        public void opInequality_CustomSettings_CustomSettings_Same()
        {
            var expression1 = new CustomSettings();
            var expression2 = expression1;

            Assert.False(expression1 != expression2);
        }

        [Fact]
        public void opInequality_CustomSettings_CustomSettings_True()
        {
            var expression1 = new CustomSettings("foo");
            var expression2 = new CustomSettings("bar");

            Assert.True(expression1 != expression2);
        }

        [Fact]
        public void opLesser_CustomSettingsNull_CustomSettings()
        {
            CustomSettings expression1 = null;
            var expression2 = new CustomSettings();

            Assert.True(expression1 < expression2);
        }

        [Fact]
        public void opLesser_CustomSettings_CustomSettingsNull()
        {
            var expression1 = new CustomSettings();
            CustomSettings expression2 = null;

            Assert.False(expression1 < expression2);
        }

        [Fact]
        public void opLesser_CustomSettings_CustomSettings_False()
        {
            var expression1 = new CustomSettings("foo");
            var expression2 = new CustomSettings("bar");

            Assert.False(expression1 < expression2);
        }

        [Fact]
        public void opLesser_CustomSettings_CustomSettings_Same()
        {
            var expression1 = new CustomSettings();
            var expression2 = expression1;

            Assert.False(expression1 < expression2);
        }

        [Fact]
        public void opLesser_CustomSettings_CustomSettings_True()
        {
            var expression1 = new CustomSettings("bar");
            var expression2 = new CustomSettings("foo");

            Assert.True(expression1 < expression2);
        }

        [Fact]
        public void op_CompareTo_object()
        {
            var obj = new CustomSettings();

            Assert.Equal(0, new CustomSettings().CompareTo(obj));
        }

        [Fact]
        public void op_CompareTo_objectGreater()
        {
            var obj = new CustomSettings("bar");

            Assert.True(new CustomSettings("foo").CompareTo(obj) > 0);
        }

        [Fact]
        public void op_CompareTo_objectInt32()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new CustomSettings().CompareTo(123));
        }

        [Fact]
        public void op_CompareTo_objectLesser()
        {
            var obj = new CustomSettings("foo");

            Assert.True(new CustomSettings("bar").CompareTo(obj) < 0);
        }

        [Fact]
        public void op_CompareTo_objectNull()
        {
            Assert.True(new CustomSettings().CompareTo(null) > 0);
        }

        [Fact]
        public void op_Compare_CustomSettingsGreater_CustomSettings()
        {
            var expression1 = new CustomSettings("foo");
            var expression2 = new CustomSettings("bar");

            Assert.True(CustomSettings.Compare(expression1, expression2) > 0);
        }

        [Fact]
        public void op_Compare_CustomSettingsLesser_CustomSettings()
        {
            var expression1 = new CustomSettings("bar");
            var expression2 = new CustomSettings("foo");

            Assert.True(CustomSettings.Compare(expression1, expression2) < 0);
        }

        [Fact]
        public void op_Compare_CustomSettingsNull_CustomSettings()
        {
            CustomSettings expression1 = null;
            var expression2 = new CustomSettings();

            Assert.True(CustomSettings.Compare(expression1, expression2) < 0);
        }

        [Fact]
        public void op_Compare_CustomSettings_CustomSettingsNull()
        {
            var expression1 = new CustomSettings();
            CustomSettings expression2 = null;

            Assert.True(CustomSettings.Compare(expression1, expression2) > 0);
        }

        [Fact]
        public void op_Compare_CustomSettings_CustomSettings_Equal()
        {
            var expression1 = new CustomSettings();
            var expression2 = new CustomSettings();

            Assert.Equal(0, CustomSettings.Compare(expression1, expression2));
        }

        [Fact]
        public void op_Compare_CustomSettings_CustomSettings_Same()
        {
            var expression1 = new CustomSettings();
            var expression2 = expression1;

            Assert.Equal(0, CustomSettings.Compare(expression1, expression2));
        }

        [Fact]
        public void op_Equals_object()
        {
            var obj = new CustomSettings();

            Assert.True(new CustomSettings().Equals(obj));
        }

        [Fact]
        public void op_Equals_objectNull()
        {
            Assert.False(new CustomSettings().Equals(null));
        }

        [Fact]
        public void op_Equals_objectString()
        {
            Assert.False(new CustomSettings("test").Equals("test"));
        }

        [Fact]
        public void op_Equals_object_this()
        {
            var obj = new CustomSettings();

            Assert.True(obj.Equals(obj));
        }

        [Fact]
        public void op_GetHashCode()
        {
            Assert.NotEqual(0, new CustomSettings().GetHashCode());
        }

        [Fact]
        public void op_ToString()
        {
            Assert.Equal("setting=\"test\"", new CustomSettings("test").ToString());
        }

        [Fact]
        public void prop_Setting_get()
        {
            const string expected = "test";
            var actual = new CustomSettings(expected).Setting;

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void prop_Setting_getDefault()
        {
            const string expected = "default";
            var actual = new CustomSettings().Setting;

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void prop_Setting_set()
        {
            var obj = new CustomSettings();

            const string expected = "test";
            obj.Setting = expected;

            var actual = obj.Setting;

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void prop_Setting_setEmpty()
        {
            var obj = new CustomSettings();

            var expected = string.Empty;
            obj.Setting = expected;

            var actual = obj.Setting;

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void prop_Setting_setNull()
        {
            Assert.Throws<ArgumentNullException>(() => new CustomSettings().Setting = null as string);
        }
    }
}